#pragma once
#include <iostream>
using namespace std;
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <cstring>
#include <string.h>
#include <netinet/in.h>
#include <string>

namespace Server
{
    class tcpServer
    {
    public:
        tcpServer(const uint16_t &port = 8080) : _port(port), _listen_sock(-1)
        {
        }

        void initServer()
        {
            _listen_sock = socket(AF_INET, SOCK_STREAM, 0);
            if (_listen_sock < 0)
            {
                perror("socket errno\n");
                exit(1);
            }
            printf("socket success\n");

            // bind
            sockaddr_in local;
            bzero(&local, sizeof(local));

            local.sin_family = AF_INET;
            local.sin_port = (_port);
            local.sin_addr.s_addr = INADDR_ANY;

            int n = bind(_listen_sock, (sockaddr *)&local, sizeof(local));
            if (n < 0)
            {
                perror("bind errno\n");
                exit(1);
            }
            printf("bind success\n");

            // 设置为监听状态
            int ret = listen(_listen_sock, 5);
            if (ret < 0)
            {
                perror("listen fail");
                exit(1);
            }
            printf("listen success\n");
        }

        void start()
        {

            while (1)
            {
                sockaddr_in peer;
                //bzero(&peer, sizeof(peer));
                socklen_t len = sizeof(peer);
                int sock = accept(_listen_sock, (sockaddr *)&peer, &len);
                if (sock < 0)
                {
                    printf("accept fail\n");
                    continue;
                }
                printf("accept success\n");
                cout << "sock:" << sock << endl;

                // 接收数据
                char buffer[128];

                ssize_t n = read(sock, buffer, sizeof(buffer) - 1);
                if (n > 0)
                {
                    buffer[n] = 0;
                    cout << buffer << endl;

                    // 再发送数据给客户端
                    string outbuffer = buffer;
                    outbuffer += "[server echo]";

                    write(sock, outbuffer.c_str(), sizeof(outbuffer));
                }
            }
        }

        ~tcpServer()
        {
        }

    private:
        int _listen_sock;
        uint16_t _port;
    };
}
